#include "RelaPlayerMgr.h"
#include "RelaNet.h"
#include "MailBoxMgr.h"

RelaNet::RelaNet(RelaPlayer& data)
	:m_owner(data)
{
	SetWaitRelease(true);
}
 
RelaNet::~RelaNet()
{
	DelSession();
}

void RelaNet::DelSession()
{
	if (m_sn.Get())
	{
		ADFacadeMgr::Ins().DelSession(m_sn.Get()->id);
	}
}

void RelaNet::Login(const Session& sn)
{
	DelSession();
	m_sn = sn;
	SetState(LoginState::Login);
}

void RelaNet::OnClientDisCon()
{
	if (m_state == LoginState::Login)
	{
		SetState(LoginState::Offline);
	}
}

void RelaNet::Logout()
{
	if (m_state == LoginState::Login)
	{
		DelSession();
		SetState(LoginState::Logout);
	}
}

void RelaNet::SetState(LoginState state)
{
	L_COND_V(m_state != state, "m_state=", (int)m_state, "state=", (int)state);
	auto oldState = m_state;
	m_state = state;
	switch (m_state)
	{
	case LoginState::Offline:
		L_COND_V(LoginState::Login == oldState);
		m_offlineTimer.Stop();
		m_offlineTimer.Start(5 * 60, [this]() {
			LDEBUG("offline time out, set logout");
			L_COND_V(LoginState::Offline == m_state);
			SetState(LoginState::Logout);
			});
		break;
	case LoginState::Login:
		m_offlineTimer.Stop();
		SetWaitRelease(false);
		MailBoxOptMgr::Ins().AddOpt(m_owner.Id(), [](MailBox& mailBox) {
			mailBox.SetWaitRelease(false);
			});
		break;
	case LoginState::Logout:
		m_offlineTimer.Stop();
		SetWaitRelease(true);
		MailBoxOptMgr::Ins().AddOpt(m_owner.Id(), [](MailBox& mailBox) {
			mailBox.SetWaitRelease(true);
			});
		break;
	default:
		LERROR("unknow ", (int)state);
		break;
	}
}

void RelaNet::SendToClient(uint32 cmd, const std::string& msg)
{
	if (const proto::Session* pCon = m_sn.Get())
	{
		pCon->SendToClient(cmd, msg);
	}
}

void RelaNet::SetWaitRelease(bool enable)
{
	if (enable)
	{
		m_waitReleaseTimer.Start(RelaPlayerMgr::DEL_WAIT_SPAN_SEC, [id= m_owner.Id()]() {
			auto it = gRelaPlayerMgr.m_id2data.find(id);
			L_COND_V(it != gRelaPlayerMgr.m_id2data.end());
			L_COND_V(it->second.m_Net.m_state == LoginState::Logout);
			it->second.PDEBUG("del player");
			gRelaPlayerMgr.m_id2data.erase(it);
		});
	}
	else
	{
		m_waitReleaseTimer.Stop();
	}
}

